package demo03;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
 *  创建B/S结构的TCP服务器
 */
public class TCPServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8080)) { // 开启服务器
            while (true) { // 服务器永久处于监听状态
                Socket socket = serverSocket.accept(); // 接收到客户端对象
                new Thread(() -> { // 创建新线程
                    /*
                     *  线程目标：
                     *  1. 接收客户端需求访问的目标地址
                     *  2. 回写目标地址给客户端
                     *  3. 浏览器遇到图片会单开一个线程访问图片地址，需要加入线程技术保证每个图片都能访问到
                     */
                    try (BufferedReader bufferedReader = new BufferedReader( // 字符转换流用于获得客户端需求访问的目标地址的字符信息
                            new InputStreamReader(socket.getInputStream())); // 客户端输入流->字节输入流->字符转换流
                            OutputStream outputStream = socket.getOutputStream()) {
                        /*
                         *  获取链接：
                         *  浏览器请求服务器时，会发送请求信息，其中的第一行包含了需求访问的目标地址：
                         *  GET /web/index.html HTTP/1.1 -> web/index.html
                         *  1. 使用转换流的readline()方法获取到第一行字符串
                         *  2. 使用String类的split()方法，用" "空格分割字符串，成为一个字符串数组
                         *  3. 使用数组索引下标[1]，获取到第二个字符串
                         *  4. 使用String类的substring()方法，从第"1"个索引开始记录字符串
                         *  5. 将得到的字符串存储
                         */
                        String link = bufferedReader.readLine().split(" ")[1].substring(1);
                        System.out.println(link); // 打印客户端需求访问的目标地址结果
                        /*
                         *  输出结果：（均为每开一次网页，浏览器会请求的目标地址）
                         *  web/index.html
                         *  web/img/logo2.png
                         *  web/img/header.jpg
                         *  web/img/1.jpg
                         *  web/img/title2.jpg
                         *  web/img/big01.jpg
                         *  web/img/middle01.jpg
                         *  web/img/small03.jpg
                         *  web/img/ad.jpg
                         */
                        outputStream.write("HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n".getBytes()); // 写入HTTP协议响应头,固定写法
                        outputStream.write("\r\n".getBytes()); // 必须要写入空行,否则浏览器不解析
                        try (FileInputStream fileInputStream = new FileInputStream(link)) { // 通过接收到的地址创建文件输入流，获取文件
                            byte[] bytes = new byte[1024]; // 存储读取到的字节
                            int len = 0; // 记录有效字节个数
                            while ((len = fileInputStream.read(bytes)) != -1) { // 回写地址采用一读一写，先读取目标地址的字节
                                outputStream.write(bytes, 0, len); // 再回写字节给客户端
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start(); // 开启线程
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
